package top.ivansong.cxf.registry;

import java.util.List;
import java.util.concurrent.atomic.AtomicLong;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.springframework.beans.factory.FactoryBean;
import top.ivansong.cxf.registry.api.ServiceNode;
import top.ivansong.cxf.registry.api.ServiceRegistry;


/**
 * 服务消费者代理器
 * 实现FactoryBean接口，通过proxiedClass属性注入，得到代理的服务消费者的bean
 * serviceRegistry{@link ServiceRegistry}: 注册中心
 * counts {@link AtomicLong}: 服务调用计数，用于负载均衡
 * proxiedClass{@link Class}: 代理的服务的接口
 * 
 * init() spring 启动后通过serviceRegistry{@link ServiceRegistry} 订阅proxiedClass对应的服务
 * getObject() 调用serviceRegistry获取订阅的服务节点
 * @author ivansong
 *
 */
@SuppressWarnings("rawtypes")
public class ServiceConsumerProxy implements FactoryBean {
	
	@Resource
	private ServiceRegistry serviceRegistry;
	
	private AtomicLong counts = new AtomicLong(-1);
	
	private Class proxiedClass;
	
	@PostConstruct()
	public void init() {
		serviceRegistry.subscribeService(proxiedClass.getName());
	}
	
	@Override
	public Object getObject() throws Exception {
		List<ServiceNode> serviveNodes = serviceRegistry.getServiceNodes(proxiedClass.getName());
		
		if (serviveNodes != null && !serviveNodes.isEmpty()) {
			long count = counts.incrementAndGet();
			int size = serviveNodes.size();
			int index = (int) Math.abs(count % size);
			return serviveNodes.get(index).getService();
		}
		return null;
	}

	@Override
	public Class getObjectType() {
		return proxiedClass;
	}

	@Override
	public boolean isSingleton() {
		return false;
	}
	
	public void setProxiedClass(String proxiedClass) throws ClassNotFoundException {
		this.proxiedClass = Class.forName(proxiedClass);
	}
}
